And when you try running the program on Windows NT, it promptly crashes with a memory exception.1
Initialize That String!
As you see in the sample program, the function is called with a buffer length of MAX_COMPUTERNAME_LENGTH characters. Where did that number come from? It came from the function documentation, which specifies
Windows 95 and Windows 98: GetComputerName fails if the input size is less than MAX_COMPUTERNAME_LENGTH + 1.
So the string buffer will be loaded with up to 15 characters (the value of the MAX_COMPUTERNAME_LENGTH buffer) plus the NULL termination character. When you pass the variable s$ to the API function, Visual Basic passes a pointer to a NULL-terminated string buffer to the function. How long is the buffer during the initial call? One bytejust the NULL termination character. The initial string is empty.
But the API call doesn't know that the buffer is only 1 byte longyou specifically told it that the buffer is 16 bytes long. So the API function happily loads the buffer with the computer name. In doing so, it overwrites memory that is being used by something else and thus crashes or otherwise corrupts your application's memory.
It is critical that strings always be preinitialized to the necessary length.
The following line is added before the GetComputerName function call:
s$ = String$(MAX_COMPUTERNAME_LENGTH + 1, 0)
Problem solved? Not quitethe program still crashes with an exception!
What Is That Buffer Length?
You know you're finding the correct function. And you know the string is being initialized correctly. That leaves the BufferSize variable. What could be simpler than passing the size of a buffer as a parameter?
1 Windows NT is quite good at detecting attempts to access invalid memory locations and raising memory exceptions as a result. Windows 95/98 does not do quite as good a job at detecting these kinds of problems, preferring to allow memory to be quietly corrupted so that your system will crash later in a spectacular manner completely unrelated to the original cause.